#ifndef KERNEL_HPP
#define KERNEL_HPP

#include <kernel/multiboot/MemoryMap.hpp>
#include <kernel/arch/i386/interrupts/isr.hpp>
#include <cpp/allocators/PoolAllocator.hpp>
#include <cpp/allocators/MemoryManager.hpp>
#include <kernel/arch/i386/memory/paging/PageTableManager.hpp>
#include <kernel/ps2/KeyboardDriver.hpp>

class Kernel final
{
	public:
		Kernel(const multiboot::MemoryMap& memoryMap, AbstractKeyboardDriver& keyboardDriver);
		[[noreturn]] void run();
		static Kernel& getInstance();
		MemoryManager& getHeapManager();

	private:
		static constexpr size_t _heapSize{paging::pageSize};
		static constexpr size_t _maxBlocksNumber{_heapSize / 8};
		typedef PoolAllocator<MemoryManager::ToAllocate, _maxBlocksNumber> HeapManagerPoolAllocator;
		friend class isr::Table;
		void printPrettyAsciiArt() const;
		static Kernel* _instance;
		paging::PageTableManager _pageTableManager;
		void* _heapAddress;
		HeapManagerPoolAllocator::PoolType _heapManagerPool;
		HeapManagerPoolAllocator _heapManagerPoolAllocator;
		MemoryManager _heapManager;
		AbstractKeyboardDriver& _keyboardDriver;
};

#endif
